package com.apestech.api.condition;

import com.apestech.api.condition.conlib.ConOper;
import com.apestech.api.condition.control.ConditionBase;
import com.apestech.api.condition.control.ConditionRange;
import com.apestech.api.tables.TableExec;
import com.apestech.formwork.condition.ConditionUtil;
import com.apestech.formwork.xml.XmlQuery;
import com.apestech.framework.db.SqlResultSet;
import com.apestech.framework.db.SqlSession;
import com.apestech.framework.db.callback.QueryCallBackHandler;
import com.apestech.framework.dictionary.modul.Table;
import com.apestech.framework.json.JSON;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.sql.callback.MasterSaveInter;
import com.apestech.framework.util.DBPub;
import com.apestech.framework.util.callback.IdKeyCallback;
import com.apestech.framework.xml.condition.modul.Condition;
import com.apestech.framework.xml.condition.modul.Dimension;
import com.apestech.framework.xml.condition.modul.Field;
import com.apestech.framework.xml.plugin.XmlPaste;
import com.apestech.framework.xml.pub.core.ElementUtil;
import com.apestech.framework.xml.table.modul.Tables;
import org.dom4j.Element;
import java.util.ArrayList;

/**
 * @author hup
 * @create 2019-01-31-17:37
 */
public class ConditionExec extends ElementUtil {
    private String conditionId;
    private Condition condition;
    private ArrayList<Tables> tables;
    private int tableSize;
    private Element root;
    private Element node;
    private boolean isbreak=true;
    private XmlPaste xmlPaste;
    private SqlSession session;
    private JSONArray gridheader;
    private ConOper conOper;

    public ConditionExec(SqlSession session, String conditionId) throws Exception {
        this.conditionId=conditionId;
        condition=ConditionUtil.getCondition(conditionId, session);
        this.session=session;
        if(condition==null){
            xmlPaste=new XmlPaste(conditionId,"conditionDef", session);
        }
        init();
    }

    public ConditionExec(XmlQuery xmlQuery, String conditionId) throws Exception {
        this.conditionId=conditionId;
        condition=ConditionUtil.getCondition(conditionId, xmlQuery.getSession());
        if(condition==null) {
            xmlPaste=new XmlPaste(conditionId,"conditionDef", xmlQuery);
        }
        session=xmlQuery.getSession();
        init();
    }

    private void init() throws Exception {
        if(condition==null){
            ConditionUtil.getAllDimensionDef(session);
            xmlPaste.expain();
            root=xmlPaste.getRoot();
            condition=xmlPaste.getCondition();
            node=xmlPaste.getNode();
        }
        if(condition==null) throw new Exception("请输入合法的条件类型ID["+conditionId+"]！");
        condition.setSession(session);
        tables=condition.getTables();
        tableSize=tables.size();
        conOper =new ConOper(condition);
    }

    public void setIsbreak(boolean isbreak) {
        this.isbreak = isbreak;
    }

    public Condition getCondition() {
        return condition;
    }

    public JSONArray getGridheader() {
        return gridheader;
    }

    public void setGridheader(JSONArray gridheader) {
        this.gridheader = gridheader;
    }

    public ConOper getConOper() {
        return conOper;
    }

    public Object saveCondtion() throws Exception {
        String xml=ElementToTxt(node);
        JSONObject param=new JSONObject();
        param.put("ID", condition.getId());
        if(param.get("ID")==null){
            param.put("ID", DBPub.getIdKey(session, "EXE_CONDITION"));
        }
        JSONArray list=session.getForJSON().table("EXE_CONDITION", param);
        if(list.size()>0) param.put("LAST_UPDATED_STAMP", list.get(0).get("LAST_UPDATED_STAMP"));
        param.put("NAME", condition.getName());
        param.put("LAST_UPDATED_STAMP_NEW", "SYSDATE");
        param.put("VALID","1");
        param.put("CREATE_DATE", "SYSDATE");
        param.put("TEXT", xml);
        if(param.get("LAST_UPDATED_STAMP")==null) param.put("LAST_UPDATED_STAMP", "SYSDATE");
        session.getForUpdate().saveTable("EXE_CONDITION", param);
        return param.get("ID");
    }

    public void updateTable() throws Exception {
        ConditionUpdateTable conditionUpdateTable=new ConditionUpdateTable(condition);
        conditionUpdateTable.updateTable(this);
    }

    public void emptyTable() throws Exception {
        for(int i=0; i<tableSize; i++){
            Tables tab=tables.get(i);
            TableExec table=new TableExec(session, tab);
            table.emptyTable();
        }
    }

    public void getDataXml() throws Exception {
        for(int i=0; i<tableSize; i++){
            Tables tab=tables.get(i);
            TableExec table=new TableExec(session, tab);
            table.getDataXml();
        }
    }

    public void addCreateTable() throws Exception {
        conOper.getConCreate().addCreateTable();
    }

    public void createTable(boolean bdrop) throws Exception {
        conOper.getConCreate().createTable(bdrop);
    }

    public void createTable(Tables tab) throws Exception {
        conOper.getConCreate().createTable(tab);
    }

    public Object saveTable() throws Exception {
        return conOper.getConSave().saveTable();
    }

    public void execTable() throws Exception {
        conOper.getConExec().execTable();
    }

    public String saveTable(String mid, JSONObject input, MasterSaveInter saveInter, IdKeyCallback idKeyCallback) throws Exception {
        return conOper.getConSave().saveTable(mid, input, saveInter, idKeyCallback);
    }

    public void execTableByM(String id, String mid, String personId) throws Exception {
        conOper.getConExec().execTableByM(id, mid, personId);
    }

    public void execTable(String tabName, Object id, String state, String personId) throws Exception {
        conOper.getConExec().execTable(tabName, id, state, personId);
    }

    public void stopTableByM(String id, String mid, String personId) throws Exception {
        conOper.getConExec().stopTableByM(id, mid, personId);
    }

    public void deleteTableByM(String id, String mid) throws Exception {
        conOper.getConDelete().deleteTableByM(id, mid);
    }

    public void deleteTable(JSONObject input, String tabName) throws Exception {
        conOper.getConDelete().deleteTable(input, tabName);
    }

    public String getMinInput()throws Exception {
        String ekey="";
        if(tableSize>0){
            Tables tab=tables.get(tableSize-1);
            String etab=tab.getExecTable();
            ekey=tab.getTable(etab).getPrimaryField();
        }
        return ekey;
    }

    public JSONObject getCondition(JSONObject input) throws Exception {
        if("1".equals(condition.getControlType())){
            return getCondition(input, new ConditionRange(condition, input));
        } else {
            return getCondition(input, new ConditionBase(condition, input));
        }

    }

    public JSONObject getCondition(JSONObject input, ConditionBase conditionBase) throws Exception {
        String mid=null;
        boolean flag=false;
        for(int i=0; i<tableSize; i++){
            Tables tab=tables.get(i);
            conditionBase.getInput().remove("SYS_TREE_FIELD");
            if(conditionBase.iniCheck(tab)){
                conditionBase.getOrderSql();
                if(conditionBase.exec(tab)){
                    flag=true;
                    mid=condition.getDimension().get(tab.getIndex()).getId();
                    break;
                }
            }
        }
        JSONObject r=conditionBase.finiExec();
        if(r==null){
            r=new JSONObject();
        }
        if(!flag) r.put("sys_break","1");
        if(isbreak && conditionBase.getMsg().size()>0){
            throw new Exception(JSON.toJSONString(conditionBase.getMsg()));
        }
        r.put("DIMENSION_ID", mid);
        if(r.get("C_ID")!=null){
            String sql="SELECT Z.ID FROM EXE_CONDITION_SUM Z WHERE Z.B_ID=#{C_ID} AND Z.CONDITION_ID=#{CONDITION_ID} AND Z.DIMENSION_ID=#{DIMENSION_ID}";
            JSONObject finalR = r;
            session.queryForResultSet(sql, r, new QueryCallBackHandler() {
                @Override
                public void getData(SqlResultSet rs, JSONArray rslist) throws Exception {
                    if(rs.next()){
                        finalR.put("C_ID", rs.getString("ID"));
                    }
                }
            });
            r=finalR;
        }
        return r;
    }

    public String qryConditionMidTabName(JSONObject input){
        String dimF=input.getString("SYS_DIM_FIELD")+","+input.getString("SYS_NO_CHECK");
        String tablename=null;
        ArrayList<Dimension> dlist=condition.getDimension();
        int dlen=dlist.size();
        for(int i=0; i<dlen; i++) {
            Dimension dim = dlist.get(i);
            if (dim.isDim(dimF)) {
                tablename=condition.getTableKey().getTabName(dim.getId());
                break;
            }
        }
        return tablename;
    }

    public JSONArray getConditionFromMutiData(JSONObject input) throws Exception {
        if("1".equals(condition.getControlType())){
            return getConditionFromMutiData(input, new ConditionRange(condition, input));
        } else {
            return getConditionFromMutiData(input, new ConditionBase(condition, input));
        }

    }

    public JSONArray getConditionFromMutiData(JSONObject input, ConditionBase conditionBase) throws Exception {
        String dimF=input.getString("SYS_DIM_FIELD")+","+input.getString("SYS_NO_CHECK");
        ArrayList<Dimension> dlist=condition.getDimension();
        int dlen=dlist.size();
        for(int i=0; i<dlen; i++){
            Dimension dim=dlist.get(i);
            if(dim.isDim(dimF)){
                String tabName=condition.getTableKey().getTabName(dim.getId());
                Tables tab=condition.getTablesById(tabName);
                if(conditionBase.iniCheck(tab)){
                    conditionBase.getOrderSql();
                    conditionBase.exec(tab);
                    return conditionBase.getResult();
                }
                break;
            }
        }
        return null;
    }

    public String getEmptyResultStr(){
        String str="";
        String sstr="";
        ArrayList<Field> fields=condition.getControlFields();
        int len=fields.size();
        for(int i=0; i<len; i++){
            String sid=fields.get(i).getId();
            if("JE".equals(sid) || "BL".equals(sid) || fields.get(i).getType().indexOf("NUMBER")>=0){
                if(!"".equals(str)) str=str+",";
                str=str+fields.get(i).getField();
            } else {
                if(!"".equals(sstr)) sstr=sstr+",";
                sstr=sstr+fields.get(i).getField();
            }
        }
        if(!"".equals(sstr)) return str+","+sstr;
        return str;
    }

    public JSONObject getSelParam(String mid, JSONObject input) throws Exception {
        String tabName=condition.getTableKey().getTabName(mid);
        Table itab=session.getDictTable(tabName+"_ITEM");
        ArrayList<String> ikey=itab.getField().getKeylist();
        ArrayList<String> inkey=input.getKeylist();
        int len=inkey.size();
        for(int i=0; i<len; i++){
            String k=inkey.get(i);
            boolean flag=false;
            for(String s: ikey){
                if(s.equals(k) || k.indexOf(s+"_")>=0){
                    flag=true;
                    break;
                }
            }
            if(flag){
                input.put("ITEM", 1);
                break;
            }
        }
        JSONArray condition=JSON.toJSONArray(input.get("condition"));
        if(condition==null){
            condition=new JSONArray();
        }
        len=condition.size();
        for(int i=0; i<len; i++){
            boolean flag=false;
            String k=condition.get(i).getString("field");
            for(String s: ikey){
                if(s.equals(k) || k.indexOf(s+"_")>=0){
                    flag=true;
                    break;
                }
            }
            if(flag){
                input.put("ITEM", 1);
                break;
            }
        }
        return input;
    }

    public String getbillQrySql(String mid, JSONObject postJSON) throws Exception {
        return conOper.getConQuery().getbillQrySql(mid, postJSON, gridheader);
    }

    public String getexecTabSql(String mid, JSONObject postJSON) throws Exception {
        return conOper.getConQuery().getexecTabSql(mid, postJSON,gridheader);
    }

    public String getimpTabSql(String mid, JSONObject postJSON) throws Exception {
        return conOper.getConQuery().getimpTabSql(mid, postJSON,gridheader);
    }

    public String getstopTabSql(String mid, JSONObject postJSON) throws Exception {
        return conOper.getConQuery().getStopTabSql(mid, postJSON,gridheader);
    }

    public String getzTabSql_Single(String mid, JSONObject postJSON) throws Exception {
        return conOper.getConQuery().getzTabSql_Single(mid, postJSON);
    }

    public String getzTabSql(String mid, JSONObject postJSON) throws Exception {
        return conOper.getConQuery().getzTabSql(mid, postJSON);
    }

    public String getmxTabSql(String mid, JSONObject postJSON) throws Exception {
        return conOper.getConQuery().getmxTabSql(mid, postJSON);
    }

    public JSONObject getDimensionField() {
        return condition.getDimensionField();
    }

    public Element getRoot() {
        return root;
    }

}
